/**********************************************************************
 * Filename: Pais.java
 * Created: 2012/04/23
 * @author Fernando Brito e Abreu
 **********************************************************************/
package iscte.es.copaPaises.businessLayer;

import java.util.Set;
import java.util.HashSet;

public class Pais implements Comparable
{
	public static Set<Pais> allInstances = new HashSet<Pais>();

	private int area;
	private String nome;
	private int populacao;
	private Continente continente;
	private Grupo grupo;

	/**********************************************************************
	 * Default constructor
	 **********************************************************************/
	public Pais()
	{
		allInstances.add(this);
	}

	/**********************************************************************
	 * Parameterized constructor
	 * @param area the area to initialize
	 * @param nome the nome to initialize
	 * @param populacao the populacao to initialize
	 * @param continente the continente to initialize
	 * @param grupo the grupo to initialize
	 **********************************************************************/
	public Pais(int area, String nome, int populacao, Continente continente, Grupo grupo)
	{
		this.area = area;
		this.nome = nome;
		this.populacao = populacao;
		this.continente = continente;
		this.grupo = grupo;
		allInstances.add(this);
	}

	/**********************************************************************
	 * Standard attribute getter
	 * @return the area of the pais
	 **********************************************************************/
	public int area()
	{
		return area;
	}

	/**********************************************************************
	 * Standard attribute setter
	 * @param area the area to set
	 **********************************************************************/
	public void setArea(int area)
	{
		this.area = area;
	}

	/**********************************************************************
	 * Standard attribute getter
	 * @return the nome of the pais
	 **********************************************************************/
	public String nome()
	{
		return nome;
	}

	/**********************************************************************
	 * Standard attribute setter
	 * @param nome the nome to set
	 **********************************************************************/
	public void setNome(String nome)
	{
		this.nome = nome;
	}

	/**********************************************************************
	 * Standard attribute getter
	 * @return the populacao of the pais
	 **********************************************************************/
	public int populacao()
	{
		return populacao;
	}

	/**********************************************************************
	 * Standard attribute setter
	 * @param populacao the populacao to set
	 **********************************************************************/
	public void setPopulacao(int populacao)
	{
		this.populacao = populacao;
	}

	/**********************************************************************
	 * ONE2MANY getter for Pais[*] <-> Continente[1]
	 * @return the continente of the pais
	 **********************************************************************/
	public Continente continente()
	{
		return continente;
	}

	/**********************************************************************
	 * ONE2MANY setter for Pais[*] <-> Continente[1]
	 * @param continente the continente to set
	 **********************************************************************/
	public void setContinente(Continente continente)
	{
		this.continente = continente;
	}

	/**********************************************************************
	 * ONE2MANY getter for Pais[*] <-> Grupo[1]
	 * @return the grupo of the pais
	 **********************************************************************/
	public Grupo grupo()
	{
		return grupo;
	}

	/**********************************************************************
	 * ONE2MANY setter for Pais[*] <-> Grupo[1]
	 * @param grupo the grupo to set
	 **********************************************************************/
	public void setGrupo(Grupo grupo)
	{
		this.grupo = grupo;
	}

	/**********************************************************************
	 * ONE2MANY getter for Pais[1] <-> Clube[*]
	 * @return the clubes of the pais
	 **********************************************************************/
	public Set<Clube> clubes()
	{
		Set<Clube> result = new HashSet<Clube>();
		for (Clube x : Clube.allInstances)
			if (x.pais()  ==  this)
				result.add(x);
				return result;
	}

	/**********************************************************************
	 * ONE2MANY setter for Pais[1] <-> Clube[*]
	 * @param clubes the clubes to set
	 **********************************************************************/
	public void setClubes(Set<Clube> clubes)
	{
		for (Clube x : clubes)
			x.setPais(this);
	}

	/**********************************************************************
	 * ONE2MANY getter for Pais[1] <-> Participante[*]
	 * @return the nacionais of the nacionalidade
	 **********************************************************************/
	public Set<Participante> nacionais()
	{
		Set<Participante> result = new HashSet<Participante>();
		for (Participante x : Participante.allInstances())
			if (x.nacionalidade()  ==  this)
				result.add(x);
				return result;
	}

	/**********************************************************************
	 * ONE2MANY setter for Pais[1] <-> Participante[*]
	 * @param nacionais the nacionais to set
	 **********************************************************************/
	public void setNacionais(Set<Participante> nacionais)
	{
		for (Participante x : nacionais)
			x.setNacionalidade(this);
	}

	/**********************************************************************
	 * MEMBER2ASSOCIATIVE getter for Pais[2] <-> Equipa[*]
	 * @return the equipa of the seleccao
	 **********************************************************************/
	public Set<Equipa> equipa()
	{
		Set<Equipa> result = new HashSet<Equipa>();
		for (Equipa x : Equipa.allInstances)
			if (x.seleccao()  ==  this)
				result.add(x);
				return result;
	}

	/**********************************************************************
	 * MEMBER2ASSOCIATIVE setter for Pais[2] <-> Equipa[*]
	 * @param equipa the equipa to set
	 **********************************************************************/
	public void setEquipa(Set<Equipa> equipa)
	{
		for (Equipa x : equipa)
			x.setSeleccao(this);
	}

	/**********************************************************************
	 * MEMBER2MEMBER getter for Pais[2] <-> Jogo[*]
	 * @return the jogo of the seleccao
	 **********************************************************************/
	public Set<Jogo> jogo()
	{
		Set<Jogo> result = new HashSet<Jogo>();
		for (Equipa x : Equipa.allInstances)
			if (x.seleccao()  ==  this)
				result.add(x.jogo());
				return result;
	}

	/**********************************************************************
	 * MEMBER2MEMBER setter for Pais[2] <-> Jogo[*]
	 * @param jogo the jogo to set
	 **********************************************************************/
	public void setJogo(Set<Jogo> jogo)
	{
		boolean encontrado;
		for (Jogo t : jogo){
			encontrado=false;
			for (Equipa x: Equipa.allInstances){
				if (x.seleccao() == this &&x.jogo()==null&&encontrado==false){
					x.setJogo(t);encontrado=true;
				}
			}
		}
	}

	/**********************************************************************
	 * ONE2MANY getter for Pais[1] <-> Cidade[*]
	 * @return the cidades of the pais
	 **********************************************************************/
	public Set<Cidade> cidades()
	{
		Set<Cidade> result = new HashSet<Cidade>();
		for (Cidade x : Cidade.allInstances)
			if (x.pais()  ==  this)
				result.add(x);
				return result;
	}

	/**********************************************************************
	 * ONE2MANY setter for Pais[1] <-> Cidade[*]
	 * @param cidades the cidades to set
	 **********************************************************************/
	public void setCidades(Set<Cidade> cidades)
	{
		for (Cidade x : cidades)
			x.setPais(this);
	}

	/**********************************************************************
	 * MEMBER2ASSOCIATIVE getter for Pais[2..*] <-> Participacao[*]
	 * @return the participacao of the participante
	 **********************************************************************/
	public Set<Participacao> participacao()
	{
		Set<Participacao> result = new HashSet<Participacao>();
		for (Participacao x : Participacao.allInstances)
			if (x.participante()  ==  this)
				result.add(x);
				return result;
	}

	/**********************************************************************
	 * MEMBER2ASSOCIATIVE setter for Pais[2..*] <-> Participacao[*]
	 * @param participacao the participacao to set
	 **********************************************************************/
	public void setParticipacao(Set<Participacao> participacao)
	{
		for (Participacao x : participacao)
			x.setParticipante(this);
	}

	/**********************************************************************
	 * MEMBER2MEMBER getter for Pais[2..*] <-> Campeonato[*]
	 * @return the participado of the participante
	 **********************************************************************/
	public Set<Campeonato> participado()
	{
		Set<Campeonato> result = new HashSet<Campeonato>();
		for (Participacao x : Participacao.allInstances)
			if (x.participante()  ==  this)
				result.add(x.participado());
				return result;
	}

	/**********************************************************************
	 * MEMBER2MEMBER setter for Pais[2..*] <-> Campeonato[*]
	 * @param participado the participado to set
	 **********************************************************************/
	public void setParticipado(Set<Campeonato> participado)
	{
		boolean encontrado;
		for (Campeonato t : participado){
			encontrado=false;
			for (Participacao x: Participacao.allInstances){
				if (x.participante() == this && x.participado()==null && encontrado==false){
					x.setParticipado(t);
					encontrado=true;
				}
			}
		}
	}

	/**********************************************************************
	 * User-defined operation specified in SOIL/OCL
	 * @param nome the nome to set
	 * @param populacao the populacao to set
	 * @param area the area to set
	 * @param continente the continente to set
	 **********************************************************************/
	public void inicializa(String nome, int populacao, int area, Continente continente)
	{
		//	DONE
		//	self.nome := nome;
		//	 self.populacao := populacao;
		//	 self.area := area;
		//	 insert (continente,self) into Continente_Pais;

		this.nome = nome;
		this.populacao = populacao;
		this.area = area;
		this.continente = continente;

	}

	//	PRE-CONDITIONS (TODO)
	/*
	pre areaAndPoupulacaoNaturais
		((populacao > 0) and (area > 0))

	 */

	//	POST-CONDITIONS (TODO)
	/*
	post paisDefinido
		nome.isDefined

	 */




	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	/**********************************************************************
	 * Object serializer
	 **********************************************************************/
	public String toString()
	{
		return "Pais [area=" + area + ", nome=" + nome + ", populacao=" + populacao + ", continente=" + continente + ", grupo=" + grupo + "]\n";
	}

	@Override
	public int compareTo(Object arg0) {
		
		return 1;
	}

}
